home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Hexen Source / G_GAME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-22  |  40.8 KB  |  2,015 lines

  1.  
  2. //**************************************************************************
  3. //**
  4. //** g_game.c : Heretic 2 : Raven Software, Corp.
  5. //**
  6. //** $RCSfile: g_game.c,v $
  7. //** $Revision: 1.68 $
  8. //** $Date: 96/01/12 13:18:07 $
  9. //** $Author: bgokey $
  10. //**
  11. //**************************************************************************
  12.  
  13. #include <string.h>
  14. #include "h2def.h"
  15. #include "p_local.h"
  16. #include "soundst.h"
  17.  
  18. #define AM_STARTKEY    9
  19.  
  20. // External functions
  21.  
  22. extern void R_InitSky(int map);
  23. extern void P_PlayerNextArtifact(player_t *player);
  24.  
  25. // Functions
  26.  
  27. boolean G_CheckDemoStatus (void);
  28. void G_ReadDemoTiccmd (ticcmd_t *cmd);
  29. void G_WriteDemoTiccmd (ticcmd_t *cmd);
  30. void G_InitNew (skill_t skill, int episode, int map);
  31.  
  32. void G_DoReborn (int playernum);
  33.  
  34. void G_DoLoadLevel(void);
  35. void G_DoInitNew(void);
  36. void G_DoNewGame(void);
  37. void G_DoLoadGame(void);
  38. void G_DoPlayDemo(void);
  39. void G_DoTeleportNewMap(void);
  40. void G_DoCompleted(void);
  41. void G_DoVictory(void);
  42. void G_DoWorldDone(void);
  43. void G_DoSaveGame(void);
  44. void G_DoSingleReborn(void);
  45.  
  46. void H2_PageTicker(void);
  47. void H2_AdvanceDemo(void);
  48.  
  49. extern boolean mn_SuicideConsole;
  50.  
  51. gameaction_t    gameaction;
  52. gamestate_t     gamestate;
  53. skill_t         gameskill;
  54. //boolean         respawnmonsters;
  55. int             gameepisode;
  56. int             gamemap;
  57. int                 prevmap;
  58.  
  59. boolean         paused;
  60. boolean         sendpause;              // send a pause event next tic
  61. boolean         sendsave;               // send a save event next tic
  62. boolean         usergame;               // ok to save / end game
  63.  
  64. boolean         timingdemo;             // if true, exit with report on completion
  65. int             starttime;              // for comparative timing purposes      
  66.  
  67. boolean         viewactive;
  68.  
  69. boolean         deathmatch;             // only if started as net death
  70. boolean         netgame;                // only true if packets are broadcast
  71. boolean         playeringame[MAXPLAYERS];
  72. player_t        players[MAXPLAYERS];
  73. pclass_t        PlayerClass[MAXPLAYERS];
  74.  
  75. // Position indicator for cooperative net-play reborn
  76. int RebornPosition;
  77.  
  78. int             consoleplayer;          // player taking events and displaying
  79. int             displayplayer;          // view being displayed
  80. int             gametic;
  81. int             levelstarttic;          // gametic at level start
  82.  
  83. char            demoname[32];
  84. boolean         demorecording;
  85. boolean         demoplayback;
  86. byte            *demobuffer, *demo_p;
  87. boolean         singledemo;             // quit after playing a demo from cmdline
  88.  
  89. boolean         precache = true;        // if true, load all graphics at start
  90.  
  91. short            consistancy[MAXPLAYERS][BACKUPTICS];
  92.  
  93. //
  94. // controls (have defaults)
  95. //
  96. int key_right, key_left, key_up, key_down;
  97. int key_strafeleft, key_straferight, key_jump;
  98. int key_fire, key_use, key_strafe, key_speed;
  99. int    key_flyup, key_flydown, key_flycenter;
  100. int    key_lookup, key_lookdown, key_lookcenter;
  101. int    key_invleft, key_invright, key_useartifact;
  102.  
  103. int mousebfire;
  104. int mousebstrafe;
  105. int mousebforward;
  106. int mousebjump;
  107.  
  108. int joybfire;
  109. int joybstrafe;
  110. int joybuse;
  111. int joybspeed;
  112. int joybjump;
  113.  
  114. int LeaveMap;
  115. static int LeavePosition;
  116.  
  117. //#define MAXPLMOVE       0x32 // Old Heretic Max move
  118.  
  119. fixed_t MaxPlayerMove[NUMCLASSES] = { 0x3C, 0x32, 0x2D, 0x31 };
  120. fixed_t forwardmove[NUMCLASSES][2] = 
  121. {
  122.     { 0x1D, 0x3C },
  123.     { 0x19, 0x32 },
  124.     { 0x16, 0x2E },
  125.     { 0x18, 0x31 }
  126. };
  127.     
  128. fixed_t sidemove[NUMCLASSES][2] = 
  129. {
  130.     { 0x1B, 0x3B },
  131.     { 0x18, 0x28 },
  132.     { 0x15, 0x25 },
  133.     { 0x17, 0x27 }
  134. };
  135.  
  136. fixed_t angleturn[3] = {640, 1280, 320};     // + slow turn
  137. #define SLOWTURNTICS    6
  138.  
  139. #define NUMKEYS 256
  140. boolean         gamekeydown[NUMKEYS];
  141. int             turnheld;                   // for accelerative turning
  142. int                 lookheld;
  143.  
  144.  
  145. boolean         mousearray[4];
  146. boolean         *mousebuttons = &mousearray[1];
  147.     // allow [-1]
  148. int             mousex, mousey;             // mouse values are used once
  149. int             dclicktime, dclickstate, dclicks;
  150. int             dclicktime2, dclickstate2, dclicks2;
  151.  
  152. int             joyxmove, joyymove;         // joystick values are repeated
  153. boolean         joyarray[5];
  154. boolean         *joybuttons = &joyarray[1];     // allow [-1]
  155.  
  156. int     savegameslot;
  157. char    savedescription[32];
  158.  
  159. int inventoryTics;
  160.  
  161. #ifdef __WATCOMC__
  162. extern externdata_t *i_ExternData;
  163. #endif
  164.  
  165. static skill_t TempSkill;
  166. static int TempEpisode;
  167. static int TempMap;
  168.  
  169. //=============================================================================
  170. /*
  171. ====================
  172. =
  173. = G_BuildTiccmd
  174. =
  175. = Builds a ticcmd from all of the available inputs or reads it from the
  176. = demo buffer.
  177. = If recording a demo, write it out
  178. ====================
  179. */
  180.  
  181. extern boolean inventory;
  182. extern int curpos;
  183. extern int inv_ptr;
  184.  
  185. extern  int             isCyberPresent;     // is CyberMan present?
  186. boolean usearti = true;
  187. void I_ReadCyberCmd (ticcmd_t *cmd);
  188.  
  189. void G_BuildTiccmd (ticcmd_t *cmd)
  190. {
  191.     int             i;
  192.     boolean         strafe, bstrafe;
  193.     int             speed, tspeed, lspeed;
  194.     int             forward, side;
  195.     int look, arti;
  196.     int flyheight;
  197.     int pClass;
  198.  
  199.     extern boolean artiskip;
  200.  
  201. #ifdef __WATCOMC__
  202.     int angleDelta;
  203.     static int oldAngle;
  204.     extern int newViewAngleOff;
  205.     static int externInvKey;
  206.     extern boolean automapactive;
  207.     event_t ev;
  208. #endif
  209.  
  210.     pClass = players[consoleplayer].class;
  211.     memset (cmd,0,sizeof(*cmd));
  212.  
  213. //    cmd->consistancy =
  214. //        consistancy[consoleplayer][(maketic*ticdup)%BACKUPTICS];
  215.  
  216.     cmd->consistancy =
  217.         consistancy[consoleplayer][maketic%BACKUPTICS];
  218.     if (isCyberPresent)
  219.         I_ReadCyberCmd (cmd);
  220.  
  221. //printf ("cons: %i\n",cmd->consistancy);
  222.     
  223.     strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe]
  224.         || joybuttons[joybstrafe];
  225.     speed = gamekeydown[key_speed] || joybuttons[joybspeed]
  226.         || joybuttons[joybspeed];
  227. #ifdef __WATCOMC__
  228.     if(useexterndriver)
  229.     {
  230.         speed |= (i_ExternData->buttons&EBT_SPEED);
  231.         strafe |= (i_ExternData->buttons&EBT_STRAFE);
  232.     }
  233. #endif
  234.  
  235.     forward = side = look = arti = flyheight = 0;
  236.     
  237. //
  238. // use two stage accelerative turning on the keyboard and joystick
  239. //
  240.     if (joyxmove < 0 || joyxmove > 0 
  241.     || gamekeydown[key_right] || gamekeydown[key_left])
  242.         turnheld += ticdup;
  243.     else
  244.         turnheld = 0;
  245.     if (turnheld < SLOWTURNTICS)
  246.         tspeed = 2;             // slow turn
  247.     else
  248.         tspeed = speed;
  249.  
  250.     if(gamekeydown[key_lookdown] || gamekeydown[key_lookup])
  251.     {
  252.         lookheld += ticdup;
  253.     }
  254.     else
  255.     {
  256.         lookheld = 0;
  257.     }
  258.     if(lookheld < SLOWTURNTICS)
  259.     {
  260.         lspeed = 1; // 3;
  261.     }
  262.     else
  263.     {
  264.         lspeed = 2; // 5;
  265.     }
  266.  
  267. //
  268. // let movement keys cancel each other out
  269. //
  270.     if(strafe)
  271.     {
  272.         if (gamekeydown[key_right])
  273.         {
  274.             side += sidemove[pClass][speed];
  275.         }
  276.         if (gamekeydown[key_left])
  277.         {
  278.             side -= sidemove[pClass][speed];
  279.         }
  280.         if (joyxmove > 0)
  281.         {
  282.             side += sidemove[pClass][speed];
  283.         }
  284.         if (joyxmove < 0)
  285.         {
  286.             side -= sidemove[pClass][speed];
  287.         }
  288.     }
  289.     else
  290.     {
  291.         if (gamekeydown[key_right])
  292.             cmd->angleturn -= angleturn[tspeed];
  293.         if (gamekeydown[key_left])
  294.             cmd->angleturn += angleturn[tspeed];
  295.         if (joyxmove > 0)
  296.             cmd->angleturn -= angleturn[tspeed];
  297.         if (joyxmove < 0)
  298.             cmd->angleturn += angleturn[tspeed];
  299.     }
  300.  
  301.     if (gamekeydown[key_up])
  302.     {
  303.         forward += forwardmove[pClass][speed];
  304.     }
  305.     if (gamekeydown[key_down])
  306.     {
  307.         forward -= forwardmove[pClass][speed];
  308.     }
  309.     if (joyymove < 0)
  310.     {
  311.         forward += forwardmove[pClass][speed];
  312.     }
  313.     if (joyymove > 0)
  314.     {
  315.         forward -= forwardmove[pClass][speed];
  316.     }
  317.     if (gamekeydown[key_straferight])
  318.     {
  319.         side += sidemove[pClass][speed];
  320.     }
  321.     if (gamekeydown[key_strafeleft])
  322.     {
  323.         side -= sidemove[pClass][speed];
  324.     }
  325.  
  326.     // Look up/down/center keys
  327.     if(gamekeydown[key_lookup])
  328.     {
  329.         look = lspeed;
  330.     }
  331.     if(gamekeydown[key_lookdown])
  332.     {
  333.         look = -lspeed;
  334.     }
  335. #ifdef __WATCOMC__
  336.     if(gamekeydown[key_lookcenter] && !useexterndriver)
  337.     {
  338.         look = TOCENTER;
  339.     }
  340. #else
  341.     if(gamekeydown[key_lookcenter])
  342.     {
  343.         look = TOCENTER;
  344.     }
  345. #endif
  346.  
  347. #ifdef __WATCOMC__
  348.     if(useexterndriver && look != TOCENTER && (gamestate == GS_LEVEL ||
  349.         gamestate == GS_INTERMISSION))
  350.     {
  351.         if(i_ExternData->moveForward)
  352.         {
  353.             forward += i_ExternData->moveForward;
  354.             if(speed)
  355.             {
  356.                 forward <<= 1;
  357.             }
  358.         }
  359.         if(i_ExternData->angleTurn)
  360.         {
  361.             if(strafe)
  362.             {
  363.                 side += i_ExternData->angleTurn;
  364.             }
  365.             else
  366.             {
  367.                 cmd->angleturn += i_ExternData->angleTurn;
  368.             }
  369.         }
  370.         if(i_ExternData->moveSideways)
  371.         {
  372.             side += i_ExternData->moveSideways;
  373.             if(speed)
  374.             {
  375.                 side <<= 1;
  376.             }
  377.         }
  378.         if(i_ExternData->buttons&EBT_CENTERVIEW)
  379.         {
  380.             look = TOCENTER;
  381.             oldAngle = 0;
  382.         }
  383.         else if(i_ExternData->pitch)
  384.         {
  385.             angleDelta = i_ExternData->pitch-oldAngle;
  386.             if(abs(angleDelta) < 35)
  387.             {
  388.                 look = angleDelta/5;
  389.             }
  390.             else
  391.             {
  392.                 look = 7*(angleDelta > 0 ? 1 : -1);
  393.             }
  394.             if(look == TOCENTER)
  395.             {
  396.                 look++;
  397.             }
  398.             oldAngle += look*5;
  399.         }
  400.         if(i_ExternData->flyDirection)
  401.         {
  402.             if(i_ExternData->flyDirection > 0)
  403.             {
  404.                 flyheight = 5;
  405.             }
  406.             else
  407.             {
  408.                 flyheight = -5;
  409.             }
  410.         }
  411.         if(abs(newViewAngleOff-i_ExternData->angleHead) < 3000)
  412.         {
  413.             newViewAngleOff = i_ExternData->angleHead;
  414.         }
  415.         if(i_ExternData->buttons&EBT_FIRE)
  416.         {
  417.             cmd->buttons |= BT_ATTACK;
  418.         }
  419.         if(i_ExternData->buttons&EBT_OPENDOOR)
  420.         {
  421.             cmd->buttons |= BT_USE;
  422.         }
  423.         if(i_ExternData->buttons&EBT_PAUSE)
  424.         {
  425.             cmd->buttons = BT_SPECIAL|BTS_PAUSE;
  426.             i_ExternData->buttons &= ~EBT_PAUSE;
  427.         }
  428.         if(externInvKey&EBT_USEARTIFACT)
  429.         {
  430.             ev.type = ev_keyup;
  431.             ev.data1 = key_useartifact;
  432.             H2_PostEvent(&ev);
  433.             externInvKey &= ~EBT_USEARTIFACT;
  434.         }
  435.         else if(i_ExternData->buttons&EBT_USEARTIFACT)
  436.         {
  437.             externInvKey |= EBT_USEARTIFACT;
  438.             ev.type = ev_keydown;
  439.             ev.data1 = key_useartifact;
  440.             H2_PostEvent(&ev);
  441.         }
  442.         if(externInvKey&EBT_INVENTORYRIGHT)
  443.         {
  444.             ev.type = ev_keyup;
  445.             ev.data1 = key_invright;
  446.             H2_PostEvent(&ev);
  447.             externInvKey &= ~EBT_INVENTORYRIGHT;
  448.         }
  449.         else if(i_ExternData->buttons&EBT_INVENTORYRIGHT)
  450.         {
  451.             externInvKey |= EBT_INVENTORYRIGHT;
  452.             ev.type = ev_keydown;
  453.             ev.data1 = key_invright;
  454.             H2_PostEvent(&ev);
  455.         }
  456.         if(externInvKey&EBT_INVENTORYLEFT)
  457.         {
  458.             ev.type = ev_keyup;
  459.             ev.data1 = key_invleft;
  460.             H2_PostEvent(&ev);
  461.             externInvKey &= ~EBT_INVENTORYLEFT;
  462.         }
  463.         else if(i_ExternData->buttons&EBT_INVENTORYLEFT)
  464.         {
  465.             externInvKey |= EBT_INVENTORYLEFT;
  466.             ev.type = ev_keydown;
  467.             ev.data1 = key_invleft;
  468.             H2_PostEvent(&ev);
  469.         }
  470.         if(i_ExternData->buttons&EBT_FLYDROP)
  471.         {
  472.             flyheight = TOCENTER;
  473.         }
  474.         if(gamestate == GS_LEVEL)
  475.         {
  476.             if(externInvKey&EBT_MAP)
  477.             { // automap
  478.                 ev.type = ev_keyup;
  479.                 ev.data1 = AM_STARTKEY;
  480.                 H2_PostEvent(&ev);
  481.                 externInvKey &= ~EBT_MAP;
  482.             }
  483.             else if(i_ExternData->buttons&EBT_MAP)
  484.             {
  485.                 externInvKey |= EBT_MAP;
  486.                 ev.type = ev_keydown;
  487.                 ev.data1 = AM_STARTKEY;
  488.                 H2_PostEvent(&ev);
  489.             }
  490.         }
  491.         if(i_ExternData->buttons&EBT_WEAPONCYCLE)
  492.         {
  493.             int curWeapon;
  494.             player_t *pl;
  495.         
  496.             pl = &players[consoleplayer];
  497.             curWeapon = pl->readyweapon;
  498.             for(curWeapon = (curWeapon+1)&3; curWeapon != pl->readyweapon;
  499.                 curWeapon = (curWeapon+1)&3)
  500.             {
  501.                 if(pl->weaponowned[curWeapon])
  502.                 {
  503.                     cmd->buttons |= BT_CHANGE;
  504.                     cmd->buttons |= curWeapon<<BT_WEAPONSHIFT;
  505.                     break;
  506.                 }
  507.             }
  508.         }
  509.         if(i_ExternData->buttons&EBT_JUMP)
  510.         {
  511.             cmd->arti |= AFLAG_JUMP;
  512.         }
  513.     }
  514. #endif
  515.  
  516.     // Fly up/down/drop keys
  517.     if(gamekeydown[key_flyup])
  518.     {
  519.         flyheight = 5; // note that the actual flyheight will be twice this
  520.     }
  521.     if(gamekeydown[key_flydown])
  522.     {
  523.         flyheight = -5;
  524.     }
  525.     if(gamekeydown[key_flycenter])
  526.     {
  527.         flyheight = TOCENTER;
  528. #ifdef __WATCOMC__
  529.         if(!useexterndriver)
  530.         {
  531.             look = TOCENTER;
  532.         }
  533. #else
  534.         look = TOCENTER;
  535. #endif
  536.     }
  537.     // Use artifact key
  538.     if(gamekeydown[key_useartifact])
  539.     {
  540.         if(gamekeydown[key_speed] && artiskip)
  541.         {
  542.             if(players[consoleplayer].inventory[inv_ptr].type != arti_none)
  543.             { // Skip an artifact
  544.                 gamekeydown[key_useartifact] = false;
  545.                 P_PlayerNextArtifact(&players[consoleplayer]);            
  546.             }
  547.         }
  548.         else
  549.         {
  550.             if(inventory)
  551.             {
  552.                 players[consoleplayer].readyArtifact =
  553.                     players[consoleplayer].inventory[inv_ptr].type;
  554.                 inventory = false;
  555.                 cmd->arti = 0;
  556.                 usearti = false;
  557.             }
  558.             else if(usearti)
  559.             {
  560.                 cmd->arti |= 
  561.                     players[consoleplayer].inventory[inv_ptr].type&AFLAG_MASK;
  562.                 usearti = false;
  563.             }
  564.         }
  565.     }
  566.     if(gamekeydown[key_jump] || mousebuttons[mousebjump]
  567.         || joybuttons[joybjump])
  568.     {
  569.         cmd->arti |= AFLAG_JUMP;
  570.     }
  571.     if(mn_SuicideConsole)
  572.     {
  573.         cmd->arti |= AFLAG_SUICIDE;
  574.         mn_SuicideConsole = false;
  575.     }
  576.  
  577.     // Artifact hot keys
  578.     if(gamekeydown[KEY_BACKSPACE] && !cmd->arti)
  579.     {
  580.         gamekeydown[KEY_BACKSPACE] = false;     // Use one of each artifact
  581.         cmd->arti = NUMARTIFACTS;
  582.     }
  583.     else if(gamekeydown[KEY_BACKSLASH] && !cmd->arti 
  584.     && (players[consoleplayer].mo->health < MAXHEALTH))
  585.     {
  586.         gamekeydown[KEY_BACKSLASH] = false;
  587.         cmd->arti = arti_health;                        
  588.     }
  589.     else if(gamekeydown[KEY_ZERO] && !cmd->arti)
  590.     {
  591.         gamekeydown[KEY_ZERO] = false;
  592.         cmd->arti = arti_poisonbag;                        
  593.     }
  594.     else if(gamekeydown[KEY_NINE] && !cmd->arti)
  595.     {
  596.         gamekeydown[KEY_NINE] = false;
  597.         cmd->arti = arti_blastradius;                    
  598.     }
  599.     else if(gamekeydown[KEY_EIGHT] && !cmd->arti)
  600.     {
  601.         gamekeydown[KEY_EIGHT] = false;
  602.         cmd->arti = arti_teleport;                        
  603.     }
  604.     else if(gamekeydown[KEY_SEVEN] && !cmd->arti)
  605.     {
  606.         gamekeydown[KEY_SEVEN] = false;
  607.         cmd->arti = arti_teleportother;                        
  608.     }
  609.     else if(gamekeydown[KEY_SIX] && !cmd->arti)
  610.     {
  611.         gamekeydown[KEY_SIX] = false;
  612.         cmd->arti = arti_egg;                        
  613.     }
  614.     else if(gamekeydown[KEY_FIVE] && !cmd->arti
  615.     && !players[consoleplayer].powers[pw_invulnerability])
  616.     {
  617.         gamekeydown[KEY_FIVE] = false;
  618.         cmd->arti = arti_invulnerability;                
  619.     }
  620.  
  621. //
  622. // buttons
  623. //
  624.     cmd->chatchar = CT_dequeueChatChar();
  625.  
  626.     if (gamekeydown[key_fire] || mousebuttons[mousebfire]
  627.         || joybuttons[joybfire])
  628.         cmd->buttons |= BT_ATTACK;
  629.  
  630.     if (gamekeydown[key_use] || joybuttons[joybuse] )
  631.     {
  632.         cmd->buttons |= BT_USE;
  633.         dclicks = 0;                    // clear double clicks if hit use button
  634.     }
  635.     
  636.     for(i = 0; i < NUMWEAPONS; i++)
  637.     {
  638.         if(gamekeydown['1'+i])
  639.         {
  640.             cmd->buttons |= BT_CHANGE;
  641.             cmd->buttons |= i<<BT_WEAPONSHIFT;
  642.             break;
  643.         }
  644.     }
  645.  
  646. //
  647. // mouse
  648. //
  649.     if (mousebuttons[mousebforward])
  650.     {
  651.         forward += forwardmove[pClass][speed];
  652.     }
  653.         
  654. //
  655. // forward double click
  656. //
  657.     if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 )
  658.     {
  659.         dclickstate = mousebuttons[mousebforward];
  660.         if (dclickstate)
  661.             dclicks++;
  662.         if (dclicks == 2)
  663.         {
  664.             cmd->buttons |= BT_USE;
  665.             dclicks = 0;
  666.         }
  667.         else
  668.             dclicktime = 0;
  669.     }
  670.     else
  671.     {
  672.         dclicktime += ticdup;
  673.         if (dclicktime > 20)
  674.         {
  675.             dclicks = 0;
  676.             dclickstate = 0;
  677.         }
  678.     }
  679.     
  680. //
  681. // strafe double click
  682. //
  683.     bstrafe = mousebuttons[mousebstrafe]
  684. || joybuttons[joybstrafe];
  685.     if (bstrafe != dclickstate2 && dclicktime2 > 1 )
  686.     {
  687.         dclickstate2 = bstrafe;
  688.         if (dclickstate2)
  689.             dclicks2++;
  690.         if (dclicks2 == 2)
  691.         {
  692.             cmd->buttons |= BT_USE;
  693.             dclicks2 = 0;
  694.         }
  695.         else
  696.             dclicktime2 = 0;
  697.     }
  698.     else
  699.     {
  700.         dclicktime2 += ticdup;
  701.         if (dclicktime2 > 20)
  702.         {
  703.             dclicks2 = 0;
  704.             dclickstate2 = 0;
  705.         }
  706.     }
  707.  
  708.     if (strafe)
  709.     {
  710.         side += mousex*2;
  711.     }
  712.     else
  713.     {
  714.         cmd->angleturn -= mousex*0x8;
  715.     }    
  716.     forward += mousey;
  717.     mousex = mousey = 0;
  718.     
  719.     if (forward > MaxPlayerMove[pClass])
  720.     {
  721.         forward = MaxPlayerMove[pClass];
  722.     }
  723.     else if (forward < -MaxPlayerMove[pClass])
  724.     {
  725.         forward = -MaxPlayerMove[pClass];
  726.     }
  727.     if (side > MaxPlayerMove[pClass])
  728.     {
  729.         side = MaxPlayerMove[pClass];
  730.     }
  731.     else if (side < -MaxPlayerMove[pClass])
  732.     {
  733.         side = -MaxPlayerMove[pClass];
  734.     }
  735.  
  736.     if(players[consoleplayer].powers[pw_speed]
  737.         && !players[consoleplayer].morphTics)
  738.     { // Adjust for a player with a speed artifact
  739.         forward = (3*forward)>>1;
  740.         side = (3*side)>>1;
  741.     }
  742.     cmd->forwardmove += forward;
  743.     cmd->sidemove += side;
  744.     if(players[consoleplayer].playerstate == PST_LIVE)
  745.     {
  746.         if(look < 0)
  747.         {
  748.             look += 16;
  749.         }
  750.         cmd->lookfly = look;
  751.     }
  752.     if(flyheight < 0)
  753.     {
  754.         flyheight += 16;
  755.     }
  756.     cmd->lookfly |= flyheight<<4;
  757.  
  758. //
  759. // special buttons
  760. //
  761.     if (sendpause)
  762.     {
  763.         sendpause = false;
  764.         cmd->buttons = BT_SPECIAL | BTS_PAUSE;
  765.     }
  766.  
  767.     if (sendsave)
  768.     {
  769.         sendsave = false;
  770.         cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT);
  771.     }
  772. }
  773.  
  774.  
  775. /*
  776. ==============
  777. =
  778. = G_DoLoadLevel
  779. =
  780. ==============
  781. */
  782.  
  783. void G_DoLoadLevel (void)
  784. {
  785.     int             i;
  786.     
  787.     levelstarttic = gametic;        // for time calculation 
  788.     gamestate = GS_LEVEL;
  789.     for (i=0 ; i<MAXPLAYERS ; i++)
  790.     {
  791.         if (playeringame[i] && players[i].playerstate == PST_DEAD)
  792.             players[i].playerstate = PST_REBORN;
  793.         memset (players[i].frags,0,sizeof(players[i].frags));
  794.     }
  795.  
  796.     SN_StopAllSequences();    
  797.     P_SetupLevel (gameepisode, gamemap, 0, gameskill);   
  798.     displayplayer = consoleplayer;      // view the guy you are playing   
  799.     starttime = I_GetTime ();
  800.     gameaction = ga_nothing;
  801.     Z_CheckHeap ();
  802.  
  803. //
  804. // clear cmd building stuff
  805. // 
  806.  
  807.     memset (gamekeydown, 0, sizeof(gamekeydown));
  808.     joyxmove = joyymove = 0;
  809.     mousex = mousey = 0;
  810.     sendpause = sendsave = paused = false;
  811.     memset (mousebuttons, 0, sizeof(mousebuttons));
  812.     memset (joybuttons, 0, sizeof(joybuttons));
  813. }
  814.  
  815.  
  816. /*
  817. ===============================================================================
  818. =
  819. = G_Responder 
  820. =
  821. = get info needed to make ticcmd_ts for the players
  822. =
  823. ===============================================================================
  824. */
  825.  
  826. boolean G_Responder(event_t *ev)
  827. {
  828.     player_t *plr;
  829.     extern boolean MenuActive;
  830.  
  831.     plr = &players[consoleplayer];
  832.     if(ev->type == ev_keyup && ev->data1 == key_useartifact)
  833.     { // flag to denote that it's okay to use an artifact
  834.         if(!inventory)
  835.         {
  836.             plr->readyArtifact = plr->inventory[inv_ptr].type;
  837.         }
  838.         usearti = true;
  839.     }
  840.  
  841.     // Check for spy mode player cycle
  842.     if(gamestate == GS_LEVEL && ev->type == ev_keydown
  843.         && ev->data1 == KEY_F12 && !deathmatch)
  844.     { // Cycle the display player
  845.         do
  846.         {
  847.             displayplayer++;
  848.             if(displayplayer == MAXPLAYERS)
  849.             {
  850.                 displayplayer = 0;
  851.             }
  852.         } while(!playeringame[displayplayer]
  853.             && displayplayer != consoleplayer);
  854.         return(true);
  855.     }
  856.  
  857.     if(CT_Responder(ev))
  858.     { // Chat ate the event
  859.         return(true);
  860.     }
  861.     if(gamestate == GS_LEVEL)
  862.     {
  863.         if(SB_Responder(ev))
  864.         { // Status bar ate the event
  865.             return(true);
  866.         }
  867.         if(AM_Responder(ev))
  868.         { // Automap ate the event
  869.             return(true);
  870.         }
  871.     }
  872.  
  873.     switch(ev->type)
  874.     {
  875.         case ev_keydown:
  876.             if(ev->data1 == key_invleft)
  877.             {
  878.                 inventoryTics = 5*35;
  879.                 if(!inventory)
  880.                 {
  881.                     inventory = true;
  882.                     break;
  883.                 }
  884.                 inv_ptr--;
  885.                 if(inv_ptr < 0)
  886.                 {
  887.                     inv_ptr = 0;
  888.                 }
  889.                 else
  890.                 {
  891.                     curpos--;
  892.                     if(curpos < 0)
  893.                     {
  894.                         curpos = 0;
  895.                     }
  896.                 }
  897.                 return(true);
  898.             }
  899.             if(ev->data1 == key_invright)
  900.             {
  901.                 inventoryTics = 5*35;
  902.                 if(!inventory)
  903.                 {
  904.                     inventory = true;
  905.                     break;
  906.                 }
  907.                 inv_ptr++;
  908.                 if(inv_ptr >= plr->inventorySlotNum)
  909.                 {
  910.                     inv_ptr--;
  911.                     if(inv_ptr < 0)
  912.                         inv_ptr = 0;
  913.                 }
  914.                 else
  915.                 {
  916.                     curpos++;
  917.                     if(curpos > 6)
  918.                     {
  919.                         curpos = 6;
  920.                     }
  921.                 }
  922.                 return(true);
  923.             }
  924.             if(ev->data1 == KEY_PAUSE && !MenuActive)
  925.             {
  926.                 sendpause = true;
  927.                 return(true);
  928.             }
  929.             if(ev->data1 < NUMKEYS)
  930.             {
  931.                 gamekeydown[ev->data1] = true;
  932.             }
  933.             return(true); // eat key down events
  934.  
  935.         case ev_keyup:
  936.             if(ev->data1 < NUMKEYS)
  937.             {
  938.                 gamekeydown[ev->data1] = false;
  939.             }
  940.             return(false); // always let key up events filter down
  941.  
  942.         case ev_mouse:
  943.             mousebuttons[0] = ev->data1&1;
  944.             mousebuttons[1] = ev->data1&2;
  945.             mousebuttons[2] = ev->data1&4;
  946.             mousex = ev->data2*(mouseSensitivity+5)/10;
  947.             mousey = ev->data3*(mouseSensitivity+5)/10;
  948.             return(true); // eat events
  949.  
  950.         case ev_joystick:
  951.             joybuttons[0] = ev->data1&1;
  952.             joybuttons[1] = ev->data1&2;
  953.             joybuttons[2] = ev->data1&4;
  954.             joybuttons[3] = ev->data1&8;
  955.             joyxmove = ev->data2;
  956.             joyymove = ev->data3;
  957.             return(true); // eat events
  958.  
  959.         default:
  960.             break;
  961.     }
  962.     return(false);
  963. }
  964.  
  965.  
  966. //==========================================================================
  967. //
  968. // G_Ticker
  969. //
  970. //==========================================================================
  971.  
  972. void G_Ticker(void)
  973. {
  974.     int i, buf;
  975.     ticcmd_t *cmd=NULL;
  976.  
  977. //
  978. // do player reborns if needed
  979. //
  980.     for (i=0 ; i<MAXPLAYERS ; i++)
  981.         if (playeringame[i] && players[i].playerstate == PST_REBORN)
  982.             G_DoReborn (i);
  983.  
  984. //
  985. // do things to change the game state
  986. //
  987.     while (gameaction != ga_nothing)
  988.     {
  989.         switch (gameaction)
  990.         {
  991.             case ga_loadlevel:
  992.                 G_DoLoadLevel();
  993.                 break;
  994.             case ga_initnew:
  995.                 G_DoInitNew();
  996.                 break;
  997.             case ga_newgame:
  998.                 G_DoNewGame();
  999.                 break;
  1000.             case ga_loadgame:
  1001.                 Draw_LoadIcon();
  1002.                 G_DoLoadGame();
  1003.                 break;
  1004.             case ga_savegame:
  1005.                 Draw_SaveIcon();
  1006.                 G_DoSaveGame();
  1007.                 break;
  1008.             case ga_singlereborn:
  1009.                 G_DoSingleReborn();
  1010.                 break;
  1011.             case ga_playdemo:
  1012.                 G_DoPlayDemo();
  1013.                 break;
  1014.             case ga_screenshot:
  1015.                 M_ScreenShot();
  1016.                 gameaction = ga_nothing;
  1017.                 break;
  1018.             case ga_leavemap:
  1019.                 Draw_TeleportIcon();
  1020.                 G_DoTeleportNewMap();
  1021.                 break;
  1022.             case ga_completed:
  1023.                 G_DoCompleted();
  1024.                 break;
  1025.             case ga_worlddone:
  1026.                 G_DoWorldDone();
  1027.                 break;
  1028.             case ga_victory:
  1029.                 F_StartFinale();
  1030.                 break;
  1031.             default:
  1032.                 break;
  1033.         }
  1034.     }
  1035.     
  1036.             
  1037. //
  1038. // get commands, check consistancy, and build new consistancy check
  1039. //
  1040.     //buf = gametic%BACKUPTICS;
  1041.  
  1042.  
  1043.     buf = (gametic/ticdup)%BACKUPTICS;
  1044.  
  1045.     for (i=0 ; i<MAXPLAYERS ; i++)
  1046.         if (playeringame[i])
  1047.         {
  1048.             cmd = &players[i].cmd;
  1049.  
  1050.             memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t));
  1051.  
  1052.             if (demoplayback)
  1053.                 G_ReadDemoTiccmd (cmd);
  1054.             if (demorecording)
  1055.                 G_WriteDemoTiccmd (cmd);
  1056.  
  1057.             if (netgame && !(gametic%ticdup) )
  1058.             {
  1059.                 if (gametic > BACKUPTICS
  1060.                 && consistancy[i][buf] != cmd->consistancy)
  1061.                 {
  1062.                     I_Error ("consistency failure (%i should be %i)",cmd->consistancy, consistancy[i][buf]);
  1063.                 }
  1064.                 if (players[i].mo)
  1065.                     consistancy[i][buf] = players[i].mo->x;
  1066.                 else
  1067.                     consistancy[i][buf] = rndindex;
  1068.             }
  1069.         }
  1070.  
  1071. //
  1072. // check for special buttons
  1073. //
  1074.     for (i=0 ; i<MAXPLAYERS ; i++)
  1075.         if (playeringame[i])
  1076.         {
  1077.             if (players[i].cmd.buttons & BT_SPECIAL)
  1078.             {
  1079.                 switch (players[i].cmd.buttons & BT_SPECIALMASK)
  1080.                 {
  1081.                 case BTS_PAUSE:
  1082.                     paused ^= 1;
  1083.                     if(paused)
  1084.                     {
  1085.                         S_PauseSound();
  1086.                     }
  1087.                     else
  1088.                     {
  1089.                         S_ResumeSound();
  1090.                     }
  1091.                     break;
  1092.                     
  1093.                 case BTS_SAVEGAME:
  1094.                     if (!savedescription[0])
  1095.                     {
  1096.                         if(netgame)
  1097.                         {
  1098.                             strcpy (savedescription, "NET GAME");
  1099.                         }
  1100.                         else
  1101.                         {
  1102.                             strcpy(savedescription, "SAVE GAME");
  1103.                         }
  1104.                     }
  1105.                     savegameslot = 
  1106.                         (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT;
  1107.                     gameaction = ga_savegame;
  1108.                     break;
  1109.                 }
  1110.             }
  1111.         }
  1112.     
  1113. // turn inventory off after a certain amount of time
  1114.     if(inventory && !(--inventoryTics))
  1115.     {
  1116.         players[consoleplayer].readyArtifact =
  1117.             players[consoleplayer].inventory[inv_ptr].type;
  1118.         inventory = false;
  1119.         cmd->arti = 0;
  1120.     }
  1121. //
  1122. // do main actions
  1123. //
  1124. //
  1125. // do main actions
  1126. //
  1127.     switch (gamestate)
  1128.     {
  1129.         case GS_LEVEL:
  1130.             P_Ticker ();
  1131.             SB_Ticker ();
  1132.             AM_Ticker ();
  1133.             CT_Ticker();
  1134.             break;
  1135.         case GS_INTERMISSION:
  1136.             IN_Ticker ();
  1137.             break;
  1138.         case GS_FINALE:
  1139.             F_Ticker();
  1140.             break;
  1141.         case GS_DEMOSCREEN:
  1142.             H2_PageTicker ();
  1143.             break;
  1144.     }       
  1145. }
  1146.  
  1147.  
  1148. /*
  1149. ==============================================================================
  1150.  
  1151.                         PLAYER STRUCTURE FUNCTIONS
  1152.  
  1153. also see P_SpawnPlayer in P_Things
  1154. ==============================================================================
  1155. */
  1156.  
  1157. //==========================================================================
  1158. //
  1159. // G_PlayerExitMap
  1160. //
  1161. // Called when the player leaves a map.
  1162. //
  1163. //==========================================================================
  1164.  
  1165. void G_PlayerExitMap(int playerNumber)
  1166. {
  1167.     int i;
  1168.     player_t *player;
  1169.     int flightPower;
  1170.  
  1171.     player = &players[playerNumber];
  1172.  
  1173. //    if(deathmatch)
  1174. //    {
  1175. //        // Strip all but one of each type of artifact
  1176. //        for(i = 0; i < player->inventorySlotNum; i++)
  1177. //        {
  1178. //            player->inventory[i].count = 1;
  1179. //        }
  1180. //        player->artifactCount = player->inventorySlotNum;
  1181. //    }
  1182. //    else
  1183.  
  1184.     // Strip all current powers (retain flight)
  1185.     flightPower = player->powers[pw_flight];
  1186.     memset(player->powers, 0, sizeof(player->powers));
  1187.     player->powers[pw_flight] = flightPower;
  1188.  
  1189.     if(deathmatch)
  1190.     {
  1191.         player->powers[pw_flight] = 0;
  1192.     }
  1193.     else
  1194.     {
  1195.         if(P_GetMapCluster(gamemap) != P_GetMapCluster(LeaveMap))
  1196.         { // Entering new cluster
  1197.             // Strip all keys
  1198.             player->keys = 0;
  1199.  
  1200.             // Strip flight artifact
  1201.             for(i = 0; i < 25; i++)
  1202.             {
  1203.                 player->powers[pw_flight] = 0;
  1204.                 P_PlayerUseArtifact(player, arti_fly);
  1205.             }
  1206.             player->powers[pw_flight] = 0;
  1207.         }
  1208.     }
  1209.  
  1210.     if(player->morphTics)
  1211.     {
  1212.         player->readyweapon = player->mo->special1; // Restore weapon
  1213.         player->morphTics = 0;
  1214.     }
  1215.     player->messageTics = 0;
  1216.     player->lookdir = 0;
  1217.     player->mo->flags &= ~MF_SHADOW; // Remove invisibility
  1218.     player->extralight = 0; // Remove weapon flashes
  1219.     player->fixedcolormap = 0; // Remove torch
  1220.     player->damagecount = 0; // No palette changes
  1221.     player->bonuscount = 0;
  1222.     player->poisoncount = 0;
  1223.     if(player == &players[consoleplayer])
  1224.     {
  1225.         SB_state = -1; // refresh the status bar
  1226.         viewangleoffset = 0;
  1227.     }
  1228. }
  1229.  
  1230. //==========================================================================
  1231. //
  1232. // G_PlayerReborn
  1233. //
  1234. // Called after a player dies.  Almost everything is cleared and
  1235. // initialized.
  1236. //
  1237. //==========================================================================
  1238.  
  1239. void G_PlayerReborn(int player)
  1240. {
  1241.     player_t *p;
  1242.     int frags[MAXPLAYERS];
  1243.     int killcount, itemcount, secretcount;
  1244.     uint worldTimer;
  1245.  
  1246.     memcpy(frags, players[player].frags, sizeof(frags));
  1247.     killcount = players[player].killcount;
  1248.     itemcount = players[player].itemcount;
  1249.     secretcount = players[player].secretcount;
  1250.     worldTimer = players[player].worldTimer;
  1251.  
  1252.     p = &players[player];
  1253.     memset(p, 0, sizeof(*p));
  1254.  
  1255.     memcpy(players[player].frags, frags, sizeof(players[player].frags));
  1256.     players[player].killcount = killcount;
  1257.     players[player].itemcount = itemcount;
  1258.     players[player].secretcount = secretcount;
  1259.     players[player].worldTimer = worldTimer;
  1260.     players[player].class = PlayerClass[player];
  1261.  
  1262.     p->usedown = p->attackdown = true; // don't do anything immediately
  1263.     p->playerstate = PST_LIVE;
  1264.     p->health = MAXHEALTH;
  1265.     p->readyweapon = p->pendingweapon = WP_FIRST;
  1266.     p->weaponowned[WP_FIRST] = true;
  1267.     p->messageTics = 0;
  1268.     p->lookdir = 0;
  1269.     localQuakeHappening[player] = false;
  1270.     if(p == &players[consoleplayer])
  1271.     {
  1272.         SB_state = -1; // refresh the status bar
  1273.         inv_ptr = 0; // reset the inventory pointer
  1274.         curpos = 0;
  1275.         viewangleoffset = 0;
  1276.     }
  1277. }
  1278.  
  1279. /*
  1280. ====================
  1281. =
  1282. = G_CheckSpot 
  1283. =
  1284. = Returns false if the player cannot be respawned at the given mapthing_t spot 
  1285. = because something is occupying it
  1286. ====================
  1287. */
  1288.  
  1289. void P_SpawnPlayer (mapthing_t *mthing);
  1290.  
  1291. boolean G_CheckSpot (int playernum, mapthing_t *mthing)
  1292. {
  1293.     fixed_t         x,y;
  1294.     subsector_t *ss;
  1295.     unsigned        an;
  1296.     mobj_t      *mo;
  1297.     
  1298.     x = mthing->x << FRACBITS;
  1299.     y = mthing->y << FRACBITS;
  1300.  
  1301.     players[playernum].mo->flags2 &= ~MF2_PASSMOBJ;
  1302.     if (!P_CheckPosition (players[playernum].mo, x, y) )
  1303.     {
  1304.         players[playernum].mo->flags2 |= MF2_PASSMOBJ;
  1305.         return false;
  1306.     }
  1307.     players[playernum].mo->flags2 |= MF2_PASSMOBJ;
  1308.  
  1309. // spawn a teleport fog
  1310.     ss = R_PointInSubsector (x,y);
  1311.     an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT;
  1312.  
  1313.     mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an],
  1314.         ss->sector->floorheight+TELEFOGHEIGHT, MT_TFOG);
  1315.  
  1316.     if (players[consoleplayer].viewz != 1)
  1317.         S_StartSound (mo, SFX_TELEPORT);  // don't start sound on first frame
  1318.  
  1319.     return true;
  1320. }
  1321.  
  1322. /*
  1323. ====================
  1324. =
  1325. = G_DeathMatchSpawnPlayer
  1326. =
  1327. = Spawns a player at one of the random death match spots
  1328. = called at level load and each death
  1329. ====================
  1330. */
  1331.  
  1332. void G_DeathMatchSpawnPlayer (int playernum)
  1333. {
  1334.     int             i,j;
  1335.     int             selections;
  1336.     
  1337.     selections = deathmatch_p - deathmatchstarts;
  1338.  
  1339.     // This check has been moved to p_setup.c:P_LoadThings()
  1340.     //if (selections < 8)
  1341.     //    I_Error ("Only %i deathmatch spots, 8 required", selections);
  1342.  
  1343.     for (j=0 ; j<20 ; j++)
  1344.     {
  1345.         i = P_Random() % selections;
  1346.         if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
  1347.         {
  1348.             deathmatchstarts[i].type = playernum+1;
  1349.             P_SpawnPlayer (&deathmatchstarts[i]);
  1350.             return;
  1351.         }
  1352.     }
  1353.  
  1354. // no good spot, so the player will probably get stuck
  1355.     P_SpawnPlayer (&playerstarts[0][playernum]);
  1356. }
  1357.  
  1358. //==========================================================================
  1359. //
  1360. // G_DoReborn
  1361. //
  1362. //==========================================================================
  1363.  
  1364. void G_DoReborn(int playernum)
  1365. {
  1366.     int i;
  1367.     boolean oldWeaponowned[NUMWEAPONS];
  1368.     int oldKeys;
  1369.     int oldPieces;
  1370.     boolean foundSpot;
  1371.     int bestWeapon;
  1372.  
  1373.     if(G_CheckDemoStatus())
  1374.     {
  1375.         return;
  1376.     }
  1377.     if(!netgame)
  1378.     {
  1379.         if(SV_RebornSlotAvailable())
  1380.         { // Use the reborn code if the slot is available
  1381.             gameaction = ga_singlereborn;
  1382.         }
  1383.         else
  1384.         { // Start a new game if there's no reborn info
  1385.             gameaction = ga_newgame;
  1386.         }
  1387.     }
  1388.     else
  1389.     { // Net-game
  1390.         players[playernum].mo->player = NULL; // Dissassociate the corpse
  1391.  
  1392.         if(deathmatch)
  1393.         { // Spawn at random spot if in death match
  1394.             G_DeathMatchSpawnPlayer(playernum);
  1395.             return;
  1396.         }
  1397.  
  1398.         // Cooperative net-play, retain keys and weapons
  1399.         oldKeys = players[playernum].keys;
  1400.         oldPieces = players[playernum].pieces;
  1401.         for(i = 0; i < NUMWEAPONS; i++)
  1402.         {
  1403.             oldWeaponowned[i] = players[playernum].weaponowned[i];
  1404.         }
  1405.  
  1406.         foundSpot = false;
  1407.         if(G_CheckSpot(playernum,
  1408.             &playerstarts[RebornPosition][playernum]))
  1409.         { // Appropriate player start spot is open
  1410.             P_SpawnPlayer(&playerstarts[RebornPosition][playernum]);
  1411.             foundSpot = true;
  1412.         }
  1413.         else
  1414.         {
  1415.             // Try to spawn at one of the other player start spots
  1416.             for(i = 0; i < MAXPLAYERS; i++)
  1417.             {
  1418.                 if(G_CheckSpot(playernum, &playerstarts[RebornPosition][i]))
  1419.                 { // Found an open start spot
  1420.  
  1421.                     // Fake as other player
  1422.                     playerstarts[RebornPosition][i].type = playernum+1;
  1423.                     P_SpawnPlayer(&playerstarts[RebornPosition][i]);
  1424.  
  1425.                     // Restore proper player type
  1426.                     playerstarts[RebornPosition][i].type = i+1;
  1427.     
  1428.                     foundSpot = true;
  1429.                     break;
  1430.                 }
  1431.             }
  1432.         }
  1433.  
  1434.         if(foundSpot == false)
  1435.         { // Player's going to be inside something
  1436.             P_SpawnPlayer(&playerstarts[RebornPosition][playernum]);
  1437.         }
  1438.  
  1439.         // Restore keys and weapons
  1440.         players[playernum].keys = oldKeys;
  1441.         players[playernum].pieces = oldPieces;
  1442.         for(bestWeapon = 0, i = 0; i < NUMWEAPONS; i++)
  1443.         {
  1444.             if(oldWeaponowned[i])
  1445.             {
  1446.                 bestWeapon = i;
  1447.                 players[playernum].weaponowned[i] = true;
  1448.             }
  1449.         }
  1450.         players[playernum].mana[MANA_1] = 25;
  1451.         players[playernum].mana[MANA_2] = 25;
  1452.         if(bestWeapon)
  1453.         { // Bring up the best weapon
  1454.             players[playernum].pendingweapon = bestWeapon;
  1455.         }
  1456.     }
  1457. }
  1458.  
  1459. void G_ScreenShot (void)
  1460. {
  1461.     gameaction = ga_screenshot;
  1462. }
  1463.  
  1464. //==========================================================================
  1465. //
  1466. // G_StartNewInit
  1467. //
  1468. //==========================================================================
  1469.  
  1470. void G_StartNewInit(void)
  1471. {
  1472.     SV_InitBaseSlot();
  1473.     SV_ClearRebornSlot();
  1474.     P_ACSInitNewGame();
  1475.     // Default the player start spot group to 0
  1476.     RebornPosition = 0;
  1477. }
  1478.  
  1479. //==========================================================================
  1480. //
  1481. // G_StartNewGame
  1482. //
  1483. //==========================================================================
  1484.  
  1485. void G_StartNewGame(skill_t skill)
  1486. {
  1487.     int realMap;
  1488.  
  1489.     G_StartNewInit();
  1490.     realMap = P_TranslateMap(1);
  1491.     if(realMap == -1)
  1492.     {
  1493.         realMap = 1;
  1494.     }
  1495.     G_InitNew(TempSkill, 1, realMap);
  1496. }
  1497.  
  1498. //==========================================================================
  1499. //
  1500. // G_TeleportNewMap
  1501. //
  1502. // Only called by the warp cheat code.  Works just like normal map to map
  1503. // teleporting, but doesn't do any interlude stuff.
  1504. //
  1505. //==========================================================================
  1506.  
  1507. void G_TeleportNewMap(int map, int position)
  1508. {
  1509.     gameaction = ga_leavemap;
  1510.     LeaveMap = map;
  1511.     LeavePosition = position;
  1512. }
  1513.  
  1514. //==========================================================================
  1515. //
  1516. // G_DoTeleportNewMap
  1517. //
  1518. //==========================================================================
  1519.  
  1520. void G_DoTeleportNewMap(void)
  1521. {
  1522.     SV_MapTeleport(LeaveMap, LeavePosition);
  1523.     gamestate = GS_LEVEL;
  1524.     gameaction = ga_nothing;
  1525.     RebornPosition = LeavePosition;
  1526. }
  1527.  
  1528. /*
  1529. boolean secretexit;
  1530. void G_ExitLevel (void)
  1531. {
  1532.     secretexit = false;
  1533.     gameaction = ga_completed;
  1534. }
  1535. void G_SecretExitLevel (void)
  1536. {
  1537.     secretexit = true;
  1538.     gameaction = ga_completed;
  1539. }
  1540. */
  1541.  
  1542. //==========================================================================
  1543. //
  1544. // G_Completed
  1545. //
  1546. // Starts intermission routine, which is used only during hub exits,
  1547. // and DeathMatch games.
  1548. //==========================================================================
  1549.  
  1550. void G_Completed(int map, int position)
  1551. {
  1552.     gameaction = ga_completed;
  1553.     LeaveMap = map;
  1554.     LeavePosition = position;
  1555. }
  1556.  
  1557. void G_DoCompleted(void)
  1558. {
  1559.     int i;
  1560.  
  1561.     gameaction = ga_nothing;
  1562.     if(G_CheckDemoStatus())
  1563.     {
  1564.         return;
  1565.     }
  1566.     for(i = 0; i < MAXPLAYERS; i++)
  1567.     {
  1568.         if(playeringame[i])
  1569.         {
  1570.             G_PlayerExitMap(i);
  1571.         }
  1572.     }
  1573.     if(LeaveMap == -1 && LeavePosition == -1)
  1574.     {
  1575.         gameaction = ga_victory;
  1576.         return;
  1577.     }
  1578.     else
  1579.     {        
  1580.         gamestate = GS_INTERMISSION;
  1581.         IN_Start();
  1582.     }
  1583.  
  1584. /*
  1585.     int i;
  1586.     static int afterSecret[3] = { 7, 5, 5 };
  1587.  
  1588.     gameaction = ga_nothing;
  1589.     if(G_CheckDemoStatus())
  1590.     {
  1591.         return;
  1592.     }
  1593.     for(i = 0; i < MAXPLAYERS; i++)
  1594.     {
  1595.         if(playeringame[i])
  1596.         {
  1597.             G_PlayerFinishLevel(i);
  1598.         }
  1599.     }
  1600.     prevmap = gamemap;
  1601.     if(secretexit == true)
  1602.     {
  1603.         gamemap = 9;
  1604.     }
  1605.     else if(gamemap == 9)
  1606.     { // Finished secret level
  1607.         gamemap = afterSecret[gameepisode-1];
  1608.     }
  1609.     else if(gamemap == 8)
  1610.     {
  1611.         gameaction = ga_victory;
  1612.         return;
  1613.     }
  1614.     else
  1615.     {
  1616.         gamemap++;
  1617.     }
  1618.     gamestate = GS_INTERMISSION;
  1619.     IN_Start();
  1620. */
  1621. }
  1622.  
  1623. //============================================================================
  1624. //
  1625. // G_WorldDone
  1626. //
  1627. //============================================================================
  1628.  
  1629. void G_WorldDone(void)
  1630. {
  1631.     gameaction = ga_worlddone;
  1632. }
  1633.  
  1634. //============================================================================
  1635. //
  1636. // G_DoWorldDone
  1637. //
  1638. //============================================================================
  1639.  
  1640. void G_DoWorldDone(void)
  1641. {
  1642.     gamestate = GS_LEVEL;
  1643.     G_DoLoadLevel();
  1644.     gameaction = ga_nothing;
  1645.     viewactive = true;
  1646. }
  1647.  
  1648. //==========================================================================
  1649. //
  1650. // G_DoSingleReborn
  1651. //
  1652. // Called by G_Ticker based on gameaction.  Loads a game from the reborn
  1653. // save slot.
  1654. //
  1655. //==========================================================================
  1656.  
  1657. void G_DoSingleReborn(void)
  1658. {
  1659.     gameaction = ga_nothing;
  1660.     SV_LoadGame(SV_GetRebornSlot());
  1661.     SB_SetClassData();
  1662. }
  1663.  
  1664. //==========================================================================
  1665. //
  1666. // G_LoadGame
  1667. //
  1668. // Can be called by the startup code or the menu task.
  1669. //
  1670. //==========================================================================
  1671.  
  1672. static int GameLoadSlot;
  1673.  
  1674. void G_LoadGame(int slot)
  1675. {
  1676.     GameLoadSlot = slot;
  1677.     gameaction = ga_loadgame;
  1678. }
  1679.  
  1680. //==========================================================================
  1681. //
  1682. // G_DoLoadGame
  1683. //
  1684. // Called by G_Ticker based on gameaction.
  1685. //
  1686. //==========================================================================
  1687.  
  1688. void G_DoLoadGame(void)
  1689. {
  1690.     gameaction = ga_nothing;
  1691.     SV_LoadGame(GameLoadSlot);
  1692.     if(!netgame)
  1693.     { // Copy the base slot to the reborn slot
  1694.         SV_UpdateRebornSlot();
  1695.     }
  1696.     SB_SetClassData();
  1697. }
  1698.  
  1699. //==========================================================================
  1700. //
  1701. // G_SaveGame
  1702. //
  1703. // Called by the menu task.  <description> is a 24 byte text string.
  1704. //
  1705. //==========================================================================
  1706.  
  1707. void G_SaveGame(int slot, char *description)
  1708. {
  1709.     savegameslot = slot;
  1710.     strcpy(savedescription, description);
  1711.     sendsave = true;
  1712. }
  1713.  
  1714. //==========================================================================
  1715. //
  1716. // G_DoSaveGame
  1717. //
  1718. // Called by G_Ticker based on gameaction.
  1719. //
  1720. //==========================================================================
  1721.  
  1722. void G_DoSaveGame(void)
  1723. {
  1724.     SV_SaveGame(savegameslot, savedescription);
  1725.     gameaction = ga_nothing;
  1726.     savedescription[0] = 0;
  1727.     P_SetMessage(&players[consoleplayer], TXT_GAMESAVED, true);
  1728. }
  1729.  
  1730. //==========================================================================
  1731. //
  1732. // G_DeferredNewGame
  1733. //
  1734. //==========================================================================
  1735.  
  1736. void G_DeferredNewGame(skill_t skill)
  1737. {
  1738.     TempSkill = skill;
  1739.     gameaction = ga_newgame;
  1740. }
  1741.  
  1742. //==========================================================================
  1743. //
  1744. // G_DoNewGame
  1745. //
  1746. //==========================================================================
  1747.  
  1748. void G_DoNewGame(void)
  1749. {
  1750.     G_StartNewGame(TempSkill);
  1751.     gameaction = ga_nothing;
  1752. }
  1753.  
  1754. /*
  1755. ====================
  1756. =
  1757. = G_InitNew
  1758. =
  1759. = Can be called by the startup code or the menu task
  1760. = consoleplayer, displayplayer, playeringame[] should be set
  1761. ====================
  1762. */
  1763.  
  1764. void G_DeferedInitNew(skill_t skill, int episode, int map)
  1765. {
  1766.     TempSkill = skill;
  1767.     TempEpisode = episode;
  1768.     TempMap = map;
  1769.     gameaction = ga_initnew;
  1770. }
  1771.  
  1772. void G_DoInitNew(void)
  1773. {
  1774.     SV_InitBaseSlot();
  1775.     G_InitNew(TempSkill, TempEpisode, TempMap);
  1776.     gameaction = ga_nothing;
  1777. }
  1778.  
  1779. void G_InitNew(skill_t skill, int episode, int map)
  1780. {
  1781.     int i;
  1782.  
  1783.     if(paused)
  1784.     {
  1785.         paused = false;
  1786.         S_ResumeSound();
  1787.     }
  1788.     if(skill < sk_baby)
  1789.     {
  1790.         skill = sk_baby;
  1791.     }
  1792.     if(skill > sk_nightmare)
  1793.     {
  1794.         skill = sk_nightmare;
  1795.     }
  1796.     if(map < 1)
  1797.     {
  1798.         map = 1;
  1799.     }
  1800.     if(map > 99)
  1801.     {
  1802.         map = 99;
  1803.     }
  1804.     M_ClearRandom();
  1805.     // Force players to be initialized upon first level load
  1806.     for(i = 0; i < MAXPLAYERS; i++)
  1807.     {
  1808.         players[i].playerstate = PST_REBORN;
  1809.         players[i].worldTimer = 0;
  1810.     }
  1811.  
  1812.     // Set up a bunch of globals
  1813.     usergame = true; // will be set false if a demo
  1814.     paused = false;
  1815.     demorecording = false;
  1816.     demoplayback = false;
  1817.     viewactive = true;
  1818.     gameepisode = episode;
  1819.     gamemap = map;
  1820.     gameskill = skill;
  1821.     BorderNeedRefresh = true;
  1822.  
  1823.     // Initialize the sky
  1824.     R_InitSky(map);
  1825.  
  1826.     // Give one null ticcmd_t
  1827.     //gametic = 0;
  1828.     //maketic = 1;
  1829.     //for (i=0 ; i<MAXPLAYERS ; i++)
  1830.     //    nettics[i] = 1; // one null event for this gametic
  1831.     //memset (localcmds,0,sizeof(localcmds));
  1832.     //memset (netcmds,0,sizeof(netcmds));
  1833.  
  1834.     G_DoLoadLevel();
  1835. }
  1836.  
  1837. /*
  1838. ===============================================================================
  1839.  
  1840.                             DEMO RECORDING
  1841.  
  1842. ===============================================================================
  1843. */
  1844.  
  1845. #define DEMOMARKER      0x80
  1846.  
  1847. void G_ReadDemoTiccmd (ticcmd_t *cmd)
  1848. {
  1849.     if (*demo_p == DEMOMARKER)
  1850.     {       // end of demo data stream
  1851.         G_CheckDemoStatus ();
  1852.         return;
  1853.     }
  1854.     cmd->forwardmove = ((signed char)*demo_p++);
  1855.     cmd->sidemove = ((signed char)*demo_p++);
  1856.     cmd->angleturn = ((unsigned char)*demo_p++)<<8;
  1857.     cmd->buttons = (unsigned char)*demo_p++;
  1858.     cmd->lookfly = (unsigned char)*demo_p++;
  1859.     cmd->arti = (unsigned char)*demo_p++;
  1860. }
  1861.  
  1862. void G_WriteDemoTiccmd (ticcmd_t *cmd)
  1863. {
  1864.     if (gamekeydown['q'])           // press q to end demo recording
  1865.         G_CheckDemoStatus ();
  1866.     *demo_p++ = cmd->forwardmove;
  1867.     *demo_p++ = cmd->sidemove;
  1868.     *demo_p++ = cmd->angleturn>>8;
  1869.     *demo_p++ = cmd->buttons;
  1870.     *demo_p++ = cmd->lookfly;
  1871.     *demo_p++ = cmd->arti;
  1872.     demo_p -= 6;
  1873.     G_ReadDemoTiccmd (cmd);         // make SURE it is exactly the same
  1874. }
  1875.  
  1876.  
  1877.  
  1878. /*
  1879. ===================
  1880. =
  1881. = G_RecordDemo
  1882. =
  1883. ===================
  1884. */
  1885.  
  1886. void G_RecordDemo (skill_t skill, int numplayers, int episode, int map, char *name)
  1887. {
  1888.     int             i;
  1889.     
  1890.     G_InitNew (skill, episode, map);
  1891.     usergame = false;
  1892.     strcpy (demoname, name);
  1893.     strcat (demoname, ".lmp");
  1894.     demobuffer = demo_p = Z_Malloc (0x20000,PU_STATIC,NULL);
  1895.     *demo_p++ = skill;
  1896.     *demo_p++ = episode;
  1897.     *demo_p++ = map;
  1898.     
  1899.     for (i=0 ; i<MAXPLAYERS ; i++)
  1900.     {
  1901.         *demo_p++ = playeringame[i];
  1902.         *demo_p++ = PlayerClass[i];
  1903.     }        
  1904.     demorecording = true;
  1905. }
  1906.  
  1907.  
  1908. /*
  1909. ===================
  1910. =
  1911. = G_PlayDemo
  1912. =
  1913. ===================
  1914. */
  1915.  
  1916. char    *defdemoname;
  1917.  
  1918. void G_DeferedPlayDemo (char *name)
  1919. {
  1920.     defdemoname = name;
  1921.     gameaction = ga_playdemo;
  1922. }
  1923.  
  1924. void G_DoPlayDemo (void)
  1925. {
  1926.     skill_t skill;
  1927.     int             i, episode, map;
  1928.     
  1929.     gameaction = ga_nothing;
  1930.     demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC);
  1931.     skill = *demo_p++;
  1932.     episode = *demo_p++;
  1933.     map = *demo_p++;
  1934.  
  1935.     for (i=0 ; i<MAXPLAYERS ; i++)
  1936.     {
  1937.         playeringame[i] = *demo_p++;
  1938.         PlayerClass[i] = *demo_p++;
  1939.     }
  1940.  
  1941.     // Initialize world info, etc.
  1942.     G_StartNewInit();
  1943.  
  1944.     precache = false;               // don't spend a lot of time in loadlevel
  1945.     G_InitNew (skill, episode, map);
  1946.     precache = true;
  1947.     usergame = false;
  1948.     demoplayback = true;
  1949. }
  1950.  
  1951.  
  1952. /*
  1953. ===================
  1954. =
  1955. = G_TimeDemo
  1956. =
  1957. ===================
  1958. */
  1959.  
  1960. void G_TimeDemo (char *name)
  1961. {
  1962.     skill_t skill;
  1963.     int             episode, map;
  1964.     
  1965.     demobuffer = demo_p = W_CacheLumpName (name, PU_STATIC);
  1966.     skill = *demo_p++;
  1967.     episode = *demo_p++;
  1968.     map = *demo_p++;
  1969.     G_InitNew (skill, episode, map);
  1970.     usergame = false;
  1971.     demoplayback = true;
  1972.     timingdemo = true;
  1973.     singletics = true;
  1974. }
  1975.  
  1976.  
  1977. /*
  1978. ===================
  1979. =
  1980. = G_CheckDemoStatus
  1981. =
  1982. = Called after a death or level completion to allow demos to be cleaned up
  1983. = Returns true if a new demo loop action will take place
  1984. ===================
  1985. */
  1986.  
  1987. boolean G_CheckDemoStatus (void)
  1988. {
  1989.     int             endtime;
  1990.     
  1991.     if (timingdemo)
  1992.     {
  1993.         endtime = I_GetTime ();
  1994.         I_Error ("timed %i gametics in %i realtics",gametic
  1995.         , endtime-starttime);
  1996.     }
  1997.     
  1998.     if (demoplayback)
  1999.     {
  2000.         if (singledemo)
  2001.             I_Quit ();
  2002.             
  2003.         Z_ChangeTag (demobuffer, PU_CACHE);
  2004.         demoplayback = false;
  2005.         H2_AdvanceDemo();
  2006.         return true;
  2007.     }
  2008.  
  2009.     if (demorecording)
  2010.     {
  2011.         *demo_p++ = DEMOMARKER;
  2012.         M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
  2013.         Z_Free (demobuffer);
  2014.         demorecording = false;
  2015.         I_Error ("Demo %s recorded",demoname);
  2016.     }
  2017.  
  2018.     return false;
  2019. }
  2020.